import axios from "axios"
import { ElMessage } from "element-plus"
import { defaultRequestInterceptors } from "./config"

import { useNProgress } from "@/hooks/web/useNProgress"
import { refreshTokenApi } from "@/api/admin/login"
import { useUserStoreWithOut } from "@/store/modules/user"
const { start, done } = useNProgress()
// 创建axios实例
const axiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_PATH,
  timeout: 5000,
})

// 存储请求的AbortController实例
const abortControllerMap = new Map()

// 请求拦截器
axiosInstance.interceptors.request.use((req: any) => {
  start()
  const controller = new AbortController()
  req.signal = controller.signal
  // 是否开启mock
  const isMock = import.meta.env.VITE_USE_MOCK
  req.url = isMock === 'true' ? "/mock" + req.url : (req.url || '')
  abortControllerMap.set(req.url, controller)
  // console.log(req);
  return req
})

let isRefreshing = false; //是否正在刷新token
let failedQueue: any[] = []; // 存储正在刷新token时的错误请求队列

// 响应拦截器
axiosInstance.interceptors.response.use(
  res => {
    const url = res.config.url || ''
    abortControllerMap.delete(url)
    done()
    return res.data
  },
  async (err) => {
    // console.log(err);

    const { status, config } = err

    // 如果长 token 过期则退出登录
    if (status === 401 && config.url.includes("/auth/refreshToken")) {
      const userStore = useUserStoreWithOut()
      ElMessage.error('登录已过期，请重新登录')
      userStore.logout()
      return
    }

    // 如果正在刷新token，发送请求是的token为过期的token，这时请求会报错，所以需要将错误请求存储起来，
    //等刷新token成功后重新发送请求
    if (isRefreshing) {
      return new Promise((resolve) => {
        failedQueue.push({
          config,
          resolve
        });
      });
    }

    if (status === 401 && !config.url.includes("/auth/refreshToken")) {
      const userStore = useUserStoreWithOut()
      // ElMessage.error('登录已过期，请重新登录')
      // userStore.logout()
      if (!isRefreshing) {
        isRefreshing = true;

        const isValide = await refreshTokenApi()
        if (isValide) {
          failedQueue.forEach((item) => {
            item.config.headers[userStore.getTokenKey ?? 'Authorization'] = userStore.getAccessToken ?? ''
            item.resolve(axiosInstance.request(item.config))
          })
        }
        isRefreshing = false;
        failedQueue = [];
        config.headers[userStore.getTokenKey ?? 'Authorization'] = userStore.getAccessToken ?? ''
        const ret = await axiosInstance.request(config)
        return ret
      }
    }

    const msg = err.response.data.msg
    if (msg) {
      ElMessage.error(msg)
    } else {
      if (status === 400) {
        ElMessage.error('请求错误')
      }

      if (status === 404) {
        ElMessage.error('接口地址不存在')
      }

      if (status === 403) {
        ElMessage.error('拒绝访问')
      }

      if (status === 500) {
        ElMessage.error('服务器错误')
      }
    }


    done()
    return Promise.reject(err)
  }
)
// 处理请求参数的拦截器
axiosInstance.interceptors.request.use(defaultRequestInterceptors)
// 处理响应结果的拦截器
// axiosInstance.interceptors.response.use(defaultResponseInterceptors)

const service = {
  // 请求
  request: (config: any) => {
    return new Promise((resolve) => {
      axiosInstance.request(config).then(res => {
        resolve(res)
      }).catch(err => {
        resolve(err.response)
      })
    })
  },

  // 取消请求
  cancelRequest: (url: string | string[]) => {
    const urlList = Array.isArray(url) ? [...url] : [url]
    for (const _url of urlList) {
      abortControllerMap.get(_url)?.abort()
      abortControllerMap.delete(_url)
    }
  },
  // 取消全部请求
  cancelAllRequest: () => {
    for (const [_, controller] of abortControllerMap) {
      controller.abort()
    }
    abortControllerMap.clear()
  }
}

export default service
